<?php
class Arm_User
{

 /**
  * Arm_User
  * 
  * @var Arm_User
  */
  private static $_instance = NULL;
  

  
  /**
   * Имя сессию для вошедших пользователей в систему
   * @var $_sessionName string
   */
  private $_sessionName = 'ARM_USER_SYSTEM';

  
  /**
   * сессия текущего пользователя, если он вошол в систему.
   * @var Zend_Session_Namespace $_session 
   */
  private $_session = NULL;
  
  /**
   * На сколько времени запоминать пользвателя в системе.
   * @var $_record integer
   */
  private $_record = 1209600;
  
  /**
   * Данные текущего пользователя.
   * 
   * @var null|false|array $_dbUserData
   */
  private $_dbUserData = null;
  
  private function __construct()
  { 
      if(Zend_Session::sessionExists() === true) {
        $session = $this->_getSession();
   	 	// проверим данные пользователя логин и пароль
   	 	if($session->login === null or $session->password === null) {
   	 		return;
   	 	}
   	 	$userActiv = $this->_isActivUser($session->login, $session->password);
     	if($userActiv === false) {
     		// пользователь был удален
     		$this->unLogin();
     		return;
     	}
      }
     
  }
  
  /**
   * Вовзращает обьект Zend_Session_Namespace
   * 
   * @return Zend_Session_Namespace
   */
   private function _getSession()
   {
   	if($this->_session !== NULL) {
   		return $this->_session;
   	}
   	  $session = new Zend_Session_Namespace($this->_sessionName, true);
   	  $this->_session = $session;
   
   return $this->_session;
   }
  

    /**
     * Arm_User
     *
     * @return Arm_User
     */
    public static function getInstance()
    {
        if(self::$_instance === NULL) {
            self::$_instance = new Arm_User();
        }
        return self::$_instance;
    }
    
    /**
     * Вернет объект Zend_Session_Namespace
     * c данными пользователя.
     * 
     * @return Zend_Session_Namespace
     */
    public function getData()
    {
    	if($this->isLogin() === false) {
    		throw new Arm_Exception(Arm_Translate::_('Вы не вошли в систему'));
    	}
       return $this->_session;
    }
    
    /**
     * Вошол пользователь в систему или нет.
     * 
     * @return bool
     */
    public function isLogin()
    {
      if($this->_session === NULL or $this->_session->id === NULL) {
      	return false;
      }
      return true;
    }
    
    /**
     * Проверит активный пользователь или нет 
     * Если был удален или отключен вернет false
     * 
     * @return bool
     */
    private function _isActivUser($login, $password)
    {
      $data = $this->_getDbDataUser($login, $password, false);
      if($data === false) {
      	return false;
      }
      $ip = Arm_Core::getRequest()->getClientIp();
      // проверим если разные ip, запишем другой ip
      $session = $this->_getSession();
      if($session->ip !== $ip) {
          $session->beforeIp = $session->ip;
          $session->ip = $ip;
      }
      
      // запишем данные в сессию возможно были изменения
      $session = $this->_getSession();
      foreach ($data as $k=>$v) {
        $session->{$k} = $v;    
      }
      
      
      return true;
    }
    
    /**
     * Фильтрует login
     * @param string $login
     */
    public function filterLogin($login)
    {
       return strtolower($login);
    }
    
    /**
     * Вход пользователя в систему, если логин и пароль верные вернет 
     * true, если не верные вернет false, если пользователь уже вошол 
     * в систему тоже вернет false.
     * 
     * @param string $login
     * @params string $password
     * @param int $record 0 - не помнить 1 помнить на определеное время 2 навсегда
     * 
     */
    public function login($login, $password,  $record = 0)
    {
      $record = (int) $record;
      $login    = $this->filterLogin($login);
      // получаем данные пользователя
      $data = $this->_getDbDataUser($login, $password);
      if($data === false) {
      		return false;
      }
       
      // запишем данные в сесию и в данные пользователя
      $session = $this->_getSession();
      foreach ($data as $k=>$v) {
      	$session->{$k} = $v;	
      }
      
      // Время входа в систему
      $session->timeLogin = time();
      // ip пользователя
      $session->ip = Arm_Core::getRequest()->getClientIp();
      $session->beforeIp = $session->ip;
      // запоминаем пользователя если нужно на определеное время	
      if(1 === $record) {
      	Zend_Session::rememberMe($this->_record);
      }
      // запоминаем пользователя на всегда если указан 2
      if(2 === $record) {
      	Zend_Session::rememberMe(316224000);
      }
      
      // блокируем сесию возможно только чтение.
      //$session->lock();
      return true;
    }
    
    /**
     * Выход с системы пользователя
     * 
     * @return void
     */
    public function unLogin()
    {
      Zend_Session::forgetMe();
      $this->_session->unlock();
      $this->_session->unsetAll();
      return;
    }
    
    /**
     * Получает с базы данных один раз данные пользователя.
     * @param unknown_type $login
     * @param unknown_type $password
     */
    protected function _getDbDataUser($login, $password, $codePassword = true)
    {
      if($this->_dbUserData !== null) {	
      	return $this->_dbUserData;
      }
      $model = new User_Model_User();
      $this->_dbUserData =  $model->getDataUser($login, $password, $codePassword);     
      if($this->_dbUserData === false) {
      	$this->_dbUserData = null;
      	return false;
      }
      return $this->_dbUserData;
    }

    /**
     * Вернет названия групы пользователя.
     * 
     * @return string
     */
    public function getGroup()
    {
     if($this->isLogin() === false) {
     	return Arm_Acl::GROUP_GUEST;
     }
     return $this->_session->group;
    }
    
    /**
     * Вернет id текущего пользователя
     * 
     * @throw Arm_User_Exception если пользователь не вошол в систему
     * @return int
     */
    public function getId()
    {
       if($this->isLogin() === false) {
     	throw new Arm_User_Exception(Arm_Translate::_('Пользователь не вошол в систему, вы не можете получить его id'));
     }
     return (int)$this->_session->id;
    }
    
    
    /**
     * Вернет логин пользователя.
     * 
     * @return string
     */
    public function getLogin()
    {
     if($this->isLogin() === false) {
     	return Arm_Acl::GROUP_GUEST;
     }
     return $this->_session->login;
    }
    

    

}